package com.fashion.dao;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;

import javax.annotation.Resource;
import java.io.Serializable;
import java.sql.SQLException;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * Created by IntelliJ IDEA.
 * User: juventus
 * Date: 11-5-26
 * Time: 下午10:38
 */
public class BaseDaoImpl implements BaseDao {
    protected HibernateTemplate getHibernateTemplate() {
        return hibernateTemplate;
    }

    private HibernateTemplate hibernateTemplate;

    @Resource(name = "hibernateTemplate")
    public void setTemplate(HibernateTemplate hibernateTemplate) {
        //  super.setHibernateTemplate(hibernateTemplate);
        this.hibernateTemplate = hibernateTemplate;
    }

    @Override
    public void saveOrUpdate(Object object) {
        hibernateTemplate.saveOrUpdate(object);
    }

    @Override
    public void delete(Object object) {
        hibernateTemplate.delete(object);
    }

    @Override
    public <T extends Object> List<T> find(String hql, Object... values) {
        return (List<T>) hibernateTemplate.find(hql, values);
    }

    @Override
    public void deleteById(String id, Class<?> clazz) {
        hibernateTemplate.delete(hibernateTemplate.get(clazz, id));
    }

    @Override
    public <T extends Object> T getEntityById(Class<T> aClass, Serializable id) {
        return hibernateTemplate.get(aClass, id);
    }

    @Override
    public void deleteAll(Collection collection) {
        if (collection.size() > 0) {
            hibernateTemplate.deleteAll(collection);
        }
    }

    @Override
    public int countItems(final String hql, final Map<String, Object> parameters) {
        return getHibernateTemplate().execute(new HibernateCallback<Long>() {
            @Override
            public Long doInHibernate(Session session) throws HibernateException, SQLException {
                Query query = session.createQuery(hql);
                query.setProperties(parameters);
                query.setCacheable(true);

                Object result = query.uniqueResult();

                if (null == result) {
                    return 0L;
                }

                return (Long) result;
            }
        }).intValue();
    }

    @Override
    public <T extends Object> List<T> findItemsWithPage(final String hql, final Map<String, Object> parameters, final int pageNumber, final int pageSize) {
        return getHibernateTemplate().executeFind(new HibernateCallback<List<T>>() {
            @Override
            public List<T> doInHibernate(Session session) throws HibernateException, SQLException {
                Query query = session.createQuery(hql);
                query.setProperties(parameters);
                query.setFirstResult((pageNumber - 1) * pageSize);
                query.setMaxResults(pageSize);
                query.setCacheable(true);

                return query.list();
            }
        });
    }

    @Override
    public <T extends Object> List<T> findItems(final String hql, final Map<String, Object> parameters) {
        return getHibernateTemplate().executeFind(new HibernateCallback<List<T>>() {
            @Override
            public List<T> doInHibernate(Session session) throws HibernateException, SQLException {
                Query query = session.createQuery(hql);
                query.setProperties(parameters);
                query.setCacheable(true);

                return query.list();
            }
        });
    }

    @Override
    public void bulkDelete(final String hql, final String[] ids) {
        getHibernateTemplate().execute(new HibernateCallback() {
            public Object doInHibernate(Session session) throws HibernateException, SQLException {
                Query query = session.createQuery(hql);
                query.setParameterList("ids", ids);

                return query.executeUpdate();
            }
        });
    }

    @Override
    public void bulkDelete(final String hql) {
        getHibernateTemplate().execute(new HibernateCallback() {
            public Object doInHibernate(Session session) throws HibernateException, SQLException {
                Query query = session.createQuery(hql);

                return query.executeUpdate();
            }
        });
    }

    @Override
    public void bulkUpdate(final String hql, final String[] ids) {
        getHibernateTemplate().execute(new HibernateCallback() {
            public Object doInHibernate(Session session) throws HibernateException, SQLException {
                Query query = session.createQuery(hql);
                query.setParameterList("ids", ids);

                return query.executeUpdate();
            }
        });
    }
}
